package com.mars.diancan.service.impl;

import com.mars.diancan.common.ProductStatusEnum;
import com.mars.diancan.common.ResultEnum;
import com.mars.diancan.dao.ProductInfoRepository;
import com.mars.diancan.dto.CartDTO;
import com.mars.diancan.exception.DiancanException;
import com.mars.diancan.pojo.ProductInfo;
import com.mars.diancan.service.ProductInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 商品信息service实现类
 * @author MARS
 * @date 2018/6/21
 */
@Service
public class ProductInfoServiceImpl implements ProductInfoService {

    @Autowired
    private ProductInfoRepository productInfoRepository;
    @Override
    public ProductInfo findOne(String productId) {
        return productInfoRepository.findOne(productId);
    }

    @Override
    public List<ProductInfo> findUpAll() {
        return productInfoRepository.findByProductStatus(ProductStatusEnum.UP.getCode());
    }

    @Override
    public Page<ProductInfo> findAll(Pageable pageable) {
        return productInfoRepository.findAll(pageable);
    }

    @Override
    public ProductInfo save(ProductInfo productInfo) {
        return productInfoRepository.save(productInfo);
    }

    @Override
    public void increaseStock(List<CartDTO> cartDTOList) {
        for (CartDTO cartDTO :  cartDTOList) {
            // 查询商品信息
            ProductInfo productInfo = productInfoRepository.findOne(cartDTO.getProductId());
            if (productInfo ==  null ){
                throw  new DiancanException(ResultEnum.PRODUCT_NOT_EXIST);
            }
            // 增加库存
            Integer num = productInfo.getProductStock() + cartDTO.getProductQuantity();
            productInfo.setProductStock(num);
            productInfoRepository.save(productInfo);
        }
    }

    /**
     * 减库存，在多线程情况下，会出现超卖现象，利用redis的锁机制来解决
     * @param cartDTOList
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void decreaseStock(List<CartDTO> cartDTOList) {
        // 减库存，先要看购物车中的商品在 商品表中是否存在
        for (CartDTO  cartDTO : cartDTOList) {
            ProductInfo productInfo = productInfoRepository.findOne(cartDTO.getProductId());
            if (productInfo == null ) {
                throw  new DiancanException(ResultEnum.PRODUCT_NOT_EXIST);
            }

            // 减库存
            Integer result = productInfo.getProductStock() - cartDTO.getProductQuantity();
            if (result < 0 ) {
                throw  new DiancanException(ResultEnum.PRODUCT_STOCK_ERROR);
            }

            productInfo.setProductStock(result);
            productInfoRepository.save(productInfo);
        }
    }

    @Override
    public ProductInfo onSale(String productId) {
        // 查看商品是否存在
        ProductInfo productInfo = productInfoRepository.findOne(productId);
        if (productInfo == null) {
            throw new DiancanException(ResultEnum.PRODUCT_NOT_EXIST);
        }

        // 判断商品上架下架状态
        if (productInfo.getProductStatusEnum() == ProductStatusEnum.UP){
            throw new DiancanException(ResultEnum.PRODUCT_STATUS_ERROR);
        }

        productInfo.setProductStatus(ProductStatusEnum.UP.getCode());
        return productInfoRepository.save(productInfo);
    }

    @Override
    public ProductInfo offSale(String productId) {
        // 查看商品是否存在
        ProductInfo productInfo = productInfoRepository.findOne(productId);
        if (productInfo == null) {
            throw new DiancanException(ResultEnum.PRODUCT_NOT_EXIST);
        }

        // 判断商品上架下架状态
        if (productInfo.getProductStatusEnum() == ProductStatusEnum.DOWN){
            throw new DiancanException(ResultEnum.PRODUCT_STATUS_ERROR);
        }

        productInfo.setProductStatus(ProductStatusEnum.DOWN.getCode());
        return productInfoRepository.save(productInfo);
    }
}
